package es.unex.meigas.core;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;

import es.unex.meigas.gui.SimpleViewPanel;
import es.unex.meigas.gui.World2Device;

public class FixedRadiusPlot extends Plot {

	private MeigasValue m_dRadius;

	public FixedRadiusPlot(){

		super();

		m_dRadius = new MeigasValue("Radio", 0, 1000);
		m_dRadius.addChangeListener(this);

	}

	public MeigasValue getRadius() {

		return m_dRadius;

	}


	public double getArea(){

		double dRadius = m_dRadius.getValue();

		if (dRadius != NO_DATA){
			return (Math.PI * Math.pow(dRadius, 2.) / 10000.);
		}
		else{
			return NO_DATA;
		}

	}

	public Rectangle2D getBoundingBox() {

		return new Rectangle2D.Double(m_CoordX - m_dRadius.getValue(),
							   		  m_CoordY - m_dRadius.getValue(),
							   		  m_dRadius.getValue() * 2, m_dRadius.getValue() * 2);

	}

	public void paint(Graphics g, World2Device w2d) {

		if (m_dRadius.getValue() != NO_DATA){
			Graphics2D g2 = (Graphics2D) g;
			Point2D pt = new Point2D.Double(m_CoordX - m_dRadius.getValue(),
											m_CoordY + m_dRadius.getValue());
			pt = w2d.transformPoint(pt);
			double dRadius = w2d.transformDistance(m_dRadius.getValue());
			Ellipse2D ellipse = new Ellipse2D.Double(pt.getX() + SimpleViewPanel.MARGIN,
													pt.getY() + SimpleViewPanel.MARGIN,
					 								2 * dRadius, 2 * dRadius);

			g2.setColor(m_Color);
			g2.fill(ellipse);
			g2.setColor(Color.BLACK);
			g2.draw(ellipse);
		}

	}

	public double[] getDistribution(String sSpecie, int iInterval, int iParameter){

		int i;
		int iClass;
		int iClasses;
		double dDiameter;
		double dValue;
		String s;
		ArrayList trees = getTrees(getFilters());
		Tree tree;

		iClasses = (int) Math.ceil(getMaximumDiameter(trees) / (double) iInterval);

		if (iClasses == 0){
			return null;
		}

		double dArea = getArea();

		if (dArea == NO_DATA){
			return null;
		}

		double distribution[] = new double[iClasses];
		int treesCount[] = new int [iClasses];

		for (i = 0; i < iClasses; i++){
			distribution[i] = 0;
			treesCount[i] = 0;
		}

		for (i = 0; i < trees.size(); i++){
			tree = (Tree)trees.get(i);
			s = tree.getSpecie();
			if (s.equals(sSpecie) || sSpecie.equals("Todas")){
				dDiameter = tree.getDBH().getValue();
				if (dDiameter!= NO_DATA){
					switch (iParameter){
					case FREQUENCY:
						dValue = 1;
						break;
					case HEIGHT:
						dValue = tree.getHeight().getValue();
						break;
					case LOG_HEIGHT:
						dValue = tree.getLogHeight().getValue();
						break;
					case VOLUME:
						dValue = tree.getVolumeWithBark().getValue();
						break;
					case VOLUME_WITHOUT_BARK:
						dValue = tree.getVolumeWithoutBark().getValue();
						break;
					case AGE:
						dValue = tree.getAge().getValue();
						break;
					case BASIMETRIC_AREA:
						dValue = tree.getBasimetricArea();
						break;
					default:
						return null;
					}
					if (dValue!= NO_DATA){
						iClass = (int) Math.floor(dDiameter);
						iClass = Math.min(iClass, iClasses - 1);
						distribution[iClass] += dValue;
						treesCount[iClass]++;
					}
				}
			}
		}

		if (iParameter == FREQUENCY){
			for (i = 0; i < iClasses; i++){
				distribution[i] /= dArea;
			}
		}
		else{
			for (i = 0; i < iClasses; i++){
				if (treesCount[i] != 0){
					distribution[i] /= treesCount[i];
				}
			}
		}

		return distribution;

	}

	protected boolean checkData() {

		if (super.checkData()){
			if (!m_dRadius.isBetweenLimits() || m_dRadius.isNoData()){
				return false;
			}
			return true;
		}
		else{
			return false;
		}

	}

	public String[] getReport() {

		int i;
		String s;
		String[] sMessages = super.getReport();
		ArrayList messages = new ArrayList();;
		String[] sRet;

		if (m_dRadius.isNoData()){
			s = "No se ha especificado un valor para el radio de la parcela";
			messages.add(s);
		}
		else{
			if (!m_dRadius.isBetweenLimits()){
				messages.add(m_dRadius.getWrongValueMessage());
			}
		}

		if (sMessages == null){
			if (messages.size() == 0){
				return null;
			}
			else{
				sRet = new String[messages.size()];
			}
		}
		else{
			sRet = new String[sMessages.length + messages.size()];
		}

		for (i = 0; i < messages.size(); i++){
			sRet[i] = (String)messages.get(i);
		}
		if (sMessages != null){
			for (i = 0; i < sMessages.length; i++){
				sRet[i + messages.size()] = sMessages[i];
			}
		}

		return sRet;

	}

	@Override
	public DasocraticElement getNewInstance() {

		FixedRadiusPlot plot = (FixedRadiusPlot) super.getNewInstance();
		plot.getRadius().setValue(m_dRadius.getValue());
		return plot;

	}

}
